﻿package src{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.text.*;
	import flash.ui.*;
	import flash.utils.*;
	
	import org.papervision3d.objects.*;

	public final class CP extends Sprite {
		public static var cp:CP;
		//
		public static var config:Object = {
			width : 800,
			height : 600
		};
		public static var view:View;
		//主体
		public static var main:DisplayObject3D;
		//飞机
		public static var pp:PP;
		//调试器
		public static var debug:Debug;
		//
		private var speed_evg:Number = 0;
		private var speed_now:Number = 0;
		private var is_move:Boolean = false;
		private var time_bgn:Number;
		private var time_end:Number;
		private var mouse_bgn:Point;
		private var mouse_now:Point;
		public function CP():void {
			cp = this;
			//
			var context:ContextMenu = new ContextMenu();
			context.hideBuiltInItems();
			contextMenu = context;
			//
			addEventListener(Event.ADDED_TO_STAGE, stageHandler);
		}
		private function stageHandler(e:Event):void {
			stage.scaleMode = "noScale";
			stage.align = "TL";
			if (stage.stageWidth && stage.stageHeight) {
				init();
			} else {
				stage.addEventListener(Event.RESIZE, fixIEWH);
			}
		}
		private function fixIEWH(e:Event):void  {
			if (stage.stageWidth && stage.stageHeight) {
				stage.removeEventListener(Event.RESIZE, fixIEWH);
				init();
			}
		}
		private function init():void {
			view = new View();
  			addChild(view);
			//
			stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
			stage.addEventListener(MouseEvent.DOUBLE_CLICK, dbclickHandler);
			stage.addEventListener(Event.RESIZE, resizeHandler);
			resizeHandler();
		}
		//============================================================================================
		private function dbclickHandler(e:MouseEvent):void {
			debug.visible = ! debug.visible;
		}
		private function downHandler(e:MouseEvent):void {
			time_bgn = getTimer();
			mouse_bgn = new Point(stage.mouseX, stage.mouseY);
			mouse_now = mouse_bgn;
			//
			stopHandler();
			is_move = false;
			//
			stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
		}
		private function moveHandler(e:MouseEvent):void {
			is_move = true;
			speed_now = stage.mouseX - mouse_now.x;
			rotateHandler(speed_now);
			mouse_now = new Point(stage.mouseX, stage.mouseY);
			//
			var time_now:Number = getTimer();
			if (time_now - time_bgn > 500) {
				time_bgn = time_now;
				mouse_bgn = mouse_now;
			}
		}
		
		private function upHandler(e:MouseEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
			//惯性
			time_end = getTimer();
			if (is_move) {
				if (Math.abs(speed_now) > 1) {
					speed_evg = (mouse_now.x - mouse_bgn.x) / (time_end - time_bgn);
					speed_evg = Math.round(speed_evg * 100);
					stage.addEventListener(Event.ENTER_FRAME, autoHandler);
				}
			}
		}
		private function autoHandler(e:Event):void {
			var val:int = speed_evg>0?1:-1;
			speed_evg = Math.round(speed_evg * 0.9 - val);
			if (speed_evg != 0) {
				rotateHandler(speed_evg);
			} else {
				stopHandler();
			}
		}
		
		private function rotateHandler(speed:Number):void {
			main.rotationY -= speed;
		}
		private function stopHandler():void {
			stage.removeEventListener(Event.ENTER_FRAME, autoHandler);
		}
		
		//==================================================================================
		private function resizeHandler(e:Event = null):void {
			config['width'] = stage.stageWidth;
			config['height'] = stage.stageHeight;
			sendEvent(E.RESIZE);
		}
		//=======================================================================================
		public static function sendEvent(typ:String, dat:Object = null):void {
			cp.dispatchEvent(new E(typ, dat));
		}
		public static function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
			cp.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		public static function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
			cp.removeEventListener(type, listener, useCapture);
		}
		
		public static function clearChildren(parentObj:DisplayObjectContainer):void {
			while (parentObj.numChildren) {
				parentObj.removeChildAt(0);
			}
		}
	}
}